/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servidor.rmi;

import Excepcoes.AlreadyFollowing;
import Excepcoes.DoubleRegistracion;
import Excepcoes.InvalidMail;
import Excepcoes.InvalidName;
import Excepcoes.InvalidSearch;
import Excepcoes.NoDetails;
import Excepcoes.NoFollers;
import Excepcoes.NoFollowing;
import Excepcoes.NoTweets;
import Excepcoes.WrongLog;
import servidor.auxiliar.GereServer;
import common.*;
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import servidor.auxiliar.DataCliente;

/**
 *
 * @author Daniel
 */
public class RMIservice extends UnicastRemoteObject implements RMIconnectionCliente {

    private int port;
    private String host;
    private GereServer gestor;

    public RMIservice(int port, String host, GereServer gestor) throws RemoteException {
        super();
        this.gestor = gestor;
        this.port = port;
        this.host = host;
    }

    public int startService() {
        try {
            System.out.println("Setting RMI up");
            String servico = "service";
            //servico = "rmi://" + host + ":" + Integer.toString(port) + "/service";
            Registry registry = LocateRegistry.createRegistry(port);
            System.out.println("Cadeia:" + servico);
            registry.rebind(servico, this);
            System.out.println("RMI working!");
            return 0;
        } catch (RemoteException ex) {
            System.out.println("RemoteException: " + ex.getMessage());
//            try {
//                java.rmi.registry.LocateRegistry.createRegistry(port);
//            } catch (RemoteException ex1) {
//                return 3;
//            }
            return 1;
        } 
    }

    public Menssagem handleData(Menssagem mensagem) throws WrongLog, DoubleRegistracion, InvalidMail, InvalidName, NoFollers, NoFollowing, InvalidSearch, AlreadyFollowing, NoTweets, NoDetails, RemoteException {

        try {
            Menssagem resp = null;

            /*
             * ----------------------------------------
             *      Tratar de loggin
             * ----------------------------------------
             */

            System.out.println("Entrei no metodo handleData!");

            if (mensagem instanceof OpLogin) {
                System.out.println("Fazer Loggin!!!");
                resp = gestor.doLoggin(mensagem);

                GereErros gereProblemas = new GereErros();
                boolean problema = gereProblemas.erroExiste(resp);

                if (problema) {
                    System.out.println("Loggin Errado!");
                    throw new WrongLog("Loggin invalido!\nVerifique os seus dados.");
                } else {
                    return resp;
                }
            }

            /*
             * ----------------------------------------
             *      Tratar de registo
             * ----------------------------------------
             */

            if (mensagem instanceof OpRegister) {
                System.out.println("Fazer Registo!!!");
                resp = gestor.doRegister(mensagem);

                GereErros gereProblemas = new GereErros();
                int problema = gereProblemas.erroRegisto(resp);
                System.out.println("Resutado do problema:" + problema);
                if (problema != 0) {
                    if (problema == 1) {
                        System.out.println("Nome ja registado!!");
                        throw new DoubleRegistracion("Nickname ja atribuido!!!");
                    }
                    if (problema == 2) {
                        throw new InvalidMail("e-mail invalido!!!");
                    }
                    if (problema == 3) {
                        throw new InvalidName("Nome invalido.");
                    }
                } else {
                    return resp;
                }
            }

            if (gestor.getClientes().pesquisaCliente(mensagem.getEmissor()) != null) {
                /*
                 * ----------------------------------------
                 *      Tratar de Following
                 * ----------------------------------------
                 */

                if (mensagem instanceof OpFollowing) {
                    System.out.println("Ver Following!!!");
                    resp = gestor.showFollowing(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new NoFollers(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }

                /*
                 * ----------------------------------------
                 *      Tratar de Followres
                 * ----------------------------------------
                 */

                if (mensagem instanceof OpFollowers) {
                    System.out.println("Ver Followers!!!");
                    resp = gestor.showFollowers(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new NoFollowing(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }

                /*
                 * ----------------------------------------
                 *      Tratar de Pesquisa
                 * ----------------------------------------
                 */

                if (mensagem instanceof OpSearch) {
                    System.out.println("Fazer pesquisa!!!");
                    resp = gestor.showSearch(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new InvalidSearch(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }

                /*
                 * ----------------------------------------
                 *   Adicionar Followers
                 * ----------------------------------------
                 */

                if (mensagem instanceof OpFollow) {
                    System.out.println("Adicionar Follow!!!");
                    resp = gestor.doFollow(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new AlreadyFollowing(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }

                /*
                 * ----------------------------------------
                 *   Mandar Tweet
                 * ----------------------------------------
                 */

                if (mensagem.getMenssagem().contains("Tweet")) {
                    System.out.println("Mandar Tweet!!!");
                    resp = gestor.doTweet(mensagem);
                }

                /*
                 * ----------------------------------------
                 *   Ver Menssagens
                 * ----------------------------------------
                 */

                if (mensagem.getMenssagem().contains("Ver mensagens")) {
                    resp = gestor.seeTweets(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new NoTweets(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }

                /*
                 * ----------------------------------------
                 *   Ver Detalhes
                 * ----------------------------------------
                 */

                if (mensagem.getMenssagem().contains("Detalhes")) {
                    resp = gestor.showDetails(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new NoDetails(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }

                /*
                 * ----------------------------------------
                 *   Ver Minhas Menssagens
                 * ----------------------------------------
                 */

                if (mensagem.getMenssagem().contains("Minhas")) {
                    resp = gestor.seeMyTweets(mensagem);

                    GereErros gereProblemas = new GereErros();
                    boolean problema = gereProblemas.erroExiste(resp);

                    if (problema) {
                        OpErro erro = (OpErro) resp;
                        throw new NoTweets(erro.getMenssagem());
                    } else {
                        return resp;
                    }
                }
                if (mensagem.getMenssagem().contains("Loggout")) {
                    resp = gestor.fazLoggout(mensagem);
                }
            }

            System.out.println("Resposta a enviar para o cliente:"+resp.getMenssagem());
            return resp;
        } catch (Exception ex) {
            if (ex instanceof WrongLog) {
                throw new WrongLog("Loggin invalido!\nVerifique os seus dados.");
            }
            if (ex instanceof DoubleRegistracion) {
                throw new DoubleRegistracion("Nickname ja atribuido!!!");
            }
            if (ex instanceof InvalidMail) {
                throw new InvalidMail("e-mail invalido!!!");
            }
            if (ex instanceof InvalidName) {
                throw new InvalidName("Nome invalido!!!");
            }
            if (ex instanceof NoFollers) {
                throw new NoFollers("Nao Segue ninguem.");
            }
            if (ex instanceof NoFollowing) {
                throw new NoFollowing("Followers Inexistentes.");
            }
            if (ex instanceof InvalidSearch) {
                throw new InvalidSearch("O elemento a pesquisar nao consta da base de dados.");
            }
            if (ex instanceof AlreadyFollowing) {
                throw new AlreadyFollowing("O Follow que pretende adicionar ja faz parte da sua lista.");
            }
            if (ex instanceof NoTweets) {
                throw new NoTweets("Não possui tweets disponiveis.");
            }
            if (ex instanceof NoDetails) {
                throw new NoDetails("Detalhes nao definidos.");
            }
            System.out.println("[ERRO]Cliente Indisponivel\n" + ex.getMessage());
            gestor.getClientes().desliga(gestor.getClientes().pesquisaCliente(mensagem.getEmissor()));
            return null;
        }

    }

    public void adicionaLigado(RMITweetInterface recTwi, String name) {

        System.out.println("Estou no adiciona ligado!!!");

        DataCliente cliente = new DataCliente(recTwi);
        cliente.setNickname(name);
        gestor.getClientes().adicionaOnline(cliente);
        System.out.println("Cliente Adicionado!!!");
    }

    public String efectuaPing() throws RemoteException {
        try {
            String ping = "Servidor ok";
            System.out.println("Eviados 4 de 4 pacotes!!");
            return ping;
        } catch (Exception ex) {
            System.out.println("Time out!!!\n" + ex.getMessage());
            return null;
        }
    }
}
